package cn.gavin.web.interceptor;

import cn.gavin.domain.Employee;
import cn.gavin.service.impl.PermissionServiceImpl;
import cn.gavin.util.RequiredPermission;
import cn.gavin.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
// 权限拦截
public class PermissionInterceptor implements HandlerInterceptor {
    @Autowired
    private PermissionServiceImpl permissionService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从 session 中获取用户信息
//        Employee employee = (Employee) request.getSession().getAttribute(UserContext.USER_IN_SESSION);
        Employee employee = UserContext.getCurrentUser(); // 优化之后
        // 判断是否是超管
        if (employee.isAdmin()){
            return true;
        }
        // handler 是代表被拦截对象（可能是静态资源，也可能是处理方法（传进来的类型不同）），判断如果不是 HandlerMethod 类型，就直接放行
        if (!(handler instanceof HandlerMethod)){ // 判断 handler 是不是 HandlerMethod 的实例
            return true;
        }
        // 强转 HandlerMethod 类型使用 getMethodAnnotation 方法
        HandlerMethod method = (HandlerMethod) handler;
        // 获取拥有指定注解的方法
        RequiredPermission annotation = method.getMethodAnnotation(RequiredPermission.class);
        if (annotation == null){
            return true;
        }
        // 查询用户拥有的权限信息（权限表达式集合）
//        List<String> stringList = permissionService.selectByEmpId(employee.getId());
//        List<String> stringList = (List<String>)request.getSession().getAttribute(UserContext.PERMISSION_IN_SESSION);
        List<String> stringList = UserContext.getPermissions(); // 优化之后
        // 获取权限注解中的表达式
        String expression = annotation.expression();
        // 判断集合中是否包含权限表达式，是则放行，否则不放行
        if (stringList.contains(expression)){
            return true;
        }
        response.sendRedirect("/nopermission");
        return false;
    }
}
